#ifndef GRAPHICS_H
#define GRAPHICS_H

#include "Camera.h"
#include "Area.h"

#include <D3DCompiler.h>
#include <Dxgi1_3.h>
#include <atlbase.h>
#include <Windows.h>

#include <FW1FontWrapper\FW1FontWrapper.h>
#include <DirectXTK\Inc\SpriteBatch.h>
#include <DirectXTK\Inc\WICTextureLoader.h>
#include <DirectXTK\Inc\CommonStates.h>

using namespace std;
using namespace D2D1;
using namespace DirectX; //SpriteBatch is in this namespace!!

class Graphics {

	public:

        Graphics(HWND, Config*);

        //Initialize Direct3D
		void InitD3D(HWND);
		void InitPipeline();
		void InitGraphics();
        void InitRasterizerStates();
		void CleanD3D();
		Camera* GetCamera();

		//Initialize Direct2D
		ID2D1Factory *factory;	//D2D factory
		ID2D1RenderTarget *d2dRenderTarget; //D2D render target. Will be merged with D3D render target through DXGI, IIRC
		IDWriteFactory1 *writeFactory;	//DWrite factory
		IDWriteTextFormat *textFormat;	//DWrite text format
		ID2D1SolidColorBrush *whiteBrush;	//DWrite brush

		//Initialize environment geometry and texture resources
		void InitAreas();
        void CreateTextures();
        void CreateMaterials();

		//Render one frame
		void PrepareFrameRender();
		void RenderFrame(double, double);
		void DisplayStats(double);
		void RenderTextOnScreen(string, float, float, float, UINT32);
		int GetNrOfVertices();
		int GetNrOfIndices();
		vector<int> GetTextureStartIndices();

		struct CBUFFER {
			XMMATRIX Final;
			XMMATRIX Rotation;
			XMVECTOR LightVector;
			XMVECTOR LightColor;
			XMVECTOR AmbientColor;
            int textureNumber;
		};

        //geometry data
        vector<Shape::VERTEX>* allVertices;
        vector<Shape::TextureFace*>* allTextureFaces;
        int vertexCounter;

		unique_ptr<SpriteBatch> g_spriteBatch;

	private:

		HWND hWnd;
		Config* config;
		ModelFactory* modelFactory;
		Camera* camera;
		vector<Area*> Areas;

		IDXGISwapChain *swapchain;
		IDXGIFactory1 *DXGIFactory;
		IDXGIAdapter1 *graphicsAdapter;
		ID3D11Device *dev;
		ID3D11DeviceContext *devcon;

		ID3D11DepthStencilState* depthStencilState;
		D3D11_DEPTH_STENCIL_DESC depthStencilDesc;

		ID3D11InputLayout *pLayout;
        ID3D11ShaderResourceView*  currentTexture;
		ID3D11ShaderResourceView** allTextures;

		IFW1Factory* FontFactory;
		IFW1FontWrapper* FontWrapper;

        //Used to prepare rendering a frame
		int NrOfPrecedingIndicesInAllAreas;
		int NrOfPrecedingVerticesInAllAreas;
		int NrOfPrecedingTexturesInAllAreas;
        vector<int> indicesInArea;
        vector<int> textureIndicesInArea;
        vector<string> textureNamesInArea;

        //Shaders
		ID3D11VertexShader *pVS;
		ID3D11PixelShader *pPS;

        //Buffers
		ID3D11Buffer *pVBuffer;
		ID3D11Buffer *pCBuffer;
		ID3D11Buffer *pIBuffer;
        ID3D11RenderTargetView *backbuffer;
		ID3D11DepthStencilView *zBuffer;

        //Rasterizer States
        ID3D11RasterizerState* pRasterizerStateDefault;
        ID3D11RasterizerState* pRasterizerStateWireframe;

};

#endif